﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using GameView.Comment;
using GameView.Models;
using GameView.Services;
using GameView.Services.Comment;
using GameView.Services.Dtos;
using GameView.Services.Dtos.Persons;
using GameView.Services.Dtos.Project;
using GameView.Views;
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations;
using System.Windows.Controls;

namespace GameView.ViewModels
{
    public partial class UserViewModel : ObservableObject
    {
        private readonly UserService _service;
        private readonly ProjectService _proService;
        private readonly RoleService _roleService;

        public UserViewModel(UserService service, ProjectService proService, RoleService roleService)
        {
            _proService = proService;
            _service = service;
            _roleService = roleService;
            LoadData().ConfigureAwait(false);
        }
        private List<ProjectWithGamesInfo> pgs = [];
        private List<ProjectPersonRelationEntity> ppsDic = [];
        [ObservableProperty]
        private bool _isLoading = false;
        [ObservableProperty]
        private int _pageIndex = 1;
        [ObservableProperty]
        private int _pageSize = 10;
        [ObservableProperty]
        private int _totalCount = 0;
        [ObservableProperty]
        private int _totalPages = 1;
        [ObservableProperty]
        private bool _hasPrevPages = false;

        [ObservableProperty]
        private bool _hasNextPages = true;
        [ObservableProperty]
        private ObservableCollection<PersonnelOutDto> _persons;
        [ObservableProperty]
        private int _pageNumber = 1;

        [ObservableProperty]
        private Dictionary<int, string> _projectNameDic = [];
        [ObservableProperty]
        private ObservableCollection<RoleOutDto> _roleOptions = [];
        private Dictionary<int, RoleOutDto> _rolesDic = [];
        [ObservableProperty]
        private RoleOutDto _nowRole;
        [ObservableProperty]
        private PersonnelQueryDto _queryDto = new();

        [RelayCommand]
        private async Task AddNewAsync()
        {
            await ExtentHelper.GetService<IDialogService>()
          .ShowDialog<UserAddNew>();
            await LoadFromApi();
        }
        [RelayCommand]
        private async Task BidingProjectAsync()
        {
            await ExtentHelper.GetService<IDialogService>()
          .ShowDialog<WithdrawalUpdateView>();
            await LoadFromApi();
        }
        [RelayCommand]
        private async Task FirstPage()
        {
            PageIndex = 1;
            PageNumber = 1;
            await LoadFromApi();
        }

        [RelayCommand]
        private async Task PreviousPageAsync()
        {
            PageIndex--;
            PageNumber--;
            await LoadFromApi();
        }

        [RelayCommand]
        private async Task NextPageAsync()
        {
            PageIndex++;
            PageNumber++;
            await LoadFromApi();
        }

        [RelayCommand]
        private void LastPage() => PageIndex = TotalPages;
        [RelayCommand]
        private async Task ChangePageSize(object size)
        {
            ComboBoxItem cb = (ComboBoxItem)size;
            //PageSize = 20;
            if (cb.Content is string sizeStr && int.TryParse(sizeStr.Replace("条/页", ""), out var newSize))
            {
                PageSize = newSize;
                PageIndex = 1; // 重置到第一页
                await LoadFromApi();
            }
        }

        [RelayCommand]
        private async Task SearchAsync()
        {
            IsLoading = true;
            await Task.Delay(200);
            try
            {
                var validationResults = QueryDto.Validate(new ValidationContext(QueryDto)).ToList();
                if (validationResults.Any())
                {
                    GlobalMessage.Instance.ShowWarning(string.Join("\n", validationResults.Select(v => v.ErrorMessage)));
                    return;
                }

                PageIndex = 1;
                await LoadFromApi();
            }
            catch (Exception ex)
            {
                GlobalMessage.Instance.ShowError($"数据加载错误：{ex.Message}");
            }
            finally
            { IsLoading = false; }
        }
        [RelayCommand]
        private async Task EditAsync(PersonnelOutDto personnel)
        {
            IsLoading = true;
            await Task.Delay(200);
            try
            {
                if (personnel.RoleId == 1)
                {
                    GlobalMessage.Instance.ShowWarning($"不允许对管理员执行该操作！");
                    return;
                }
                var view = ExtentHelper.GetService<UserAddNew>();
                var dc = (UserAddNewViewModel)view.DataContext;
                dc.SetEdit(personnel);
                await ExtentHelper.GetService<IDialogService>().ShowDialog(view);
                await LoadFromApi();
            }
            catch (Exception ex)
            {
                GlobalMessage.Instance.ShowError($"数据加载错误：{ex.Message}");
            }
            finally
            { IsLoading = false; }
        }
        [RelayCommand]
        private async Task DeleteAsync(PersonnelOutDto personnel)
        {
            IsLoading = true;
            await Task.Delay(200);
            try
            {
                if (personnel.RoleId == 1)
                {
                    GlobalMessage.Instance.ShowWarning($"不允许对管理员执行该操作！");
                    return;
                }
                var view = new MsgViewDialogView("警告", 3002, "您确认要删除用户", personnel.Account, "的数据吗？");
                var resxx = await ExtentHelper.GetService<IDialogService>().ShowDialog(view);
                if (!(bool)resxx)
                    return;
                var res = await _service.Delete([personnel.Id]);
                if (res.StatusCode != 200)
                {
                    GlobalMessage.Instance.ShowError(JSON.Serialize(res.Errors));
                    return;
                }
                GlobalMessage.Instance.ShowSuccess($"数据删除成功！");
                await LoadFromApi();
            }
            catch (Exception ex)
            {
                GlobalMessage.Instance.ShowError($"数据加载错误：{ex.Message}");
            }
            finally
            { IsLoading = false; }
        }
        [RelayCommand]
        private async Task PasswordResetAsync(PersonnelOutDto personnel)
        {
            IsLoading = true;
            await Task.Delay(200);
            try
            {
                if (personnel.RoleId == 1)
                {
                    GlobalMessage.Instance.ShowWarning($"不允许对管理员执行该操作！");
                    return;
                }
                var view = new MsgViewDialogView("提示", 3004, "您确认要重置用户", personnel.Account, "的密码吗？");
                var resxx = await ExtentHelper.GetService<IDialogService>().ShowDialog(view);
                if (!(bool)resxx)
                    return;
                var res = await _service.ResetPassword(personnel.Id);
                if (res.StatusCode != 200)
                {
                    GlobalMessage.Instance.ShowError(JSON.Serialize(res.Errors));
                    return;
                }
                else if (res.StatusCode == 200 && !res.Data.IsNullOrEmpty())
                {
                    view = new MsgViewDialogView("提示", 3001, "用户：", personnel.Account, "新的密码为：", res.Data, ",请妥善保存您的新密码！");
                    view.SetHasCancel(false);
                    await ExtentHelper.GetService<IDialogService>().ShowDialog(view);
                }
            }
            catch (Exception ex)
            {
                GlobalMessage.Instance.ShowError($"数据加载错误：{ex.Message}");
            }
            finally
            { IsLoading = false; }
        }

        [RelayCommand]
        private async Task BindingAsync(PersonnelOutDto personnel)
        {
            IsLoading = true;
            await Task.Delay(200);
            try
            {
                if (personnel.RoleId == 1)
                {
                    GlobalMessage.Instance.ShowWarning($"不允许对管理员执行该操作！");
                    return;
                }
                var view = ExtentHelper.GetService<AssignProjectView>();
                var dc = (AssignProjectViewModel)view.DataContext;
                dc.SetPersonInfo(personnel, ppsDic);
                await ExtentHelper.GetService<IDialogService>().ShowDialog(view);
                await LoadPPS();
                await LoadFromApi();
            }
            catch (Exception ex)
            {
                GlobalMessage.Instance.ShowError($"数据加载错误：{ex.Message}");
            }
            finally
            { IsLoading = false; }
        }
        [RelayCommand]
        private async Task LoadData()
        {
            IsLoading = true;
            await Task.Delay(200);
            try
            {
                await LoadPPS();
                var res = await _proService.GetAllAsync();
                pgs = res.Data;
                _projectNameDic?.Clear();
                if (!pgs.IsNullOrEmpty())
                    foreach (var data in pgs)
                    {
                        _projectNameDic?.Add(data.Id, data.Name);
                    }
                var roles = await _roleService.GetAllAsync();
                if (!roles.Data.IsNullOrEmpty())
                {
                    RoleOptions.Clear();
                    _rolesDic.Clear();
                    foreach (var data in roles.Data)
                    {
                        RoleOptions.Add(data);
                    }
                    _rolesDic = RoleOptions.ToDictionary(q => q.Id);
                }
                await LoadFromApi();
            }
            catch (Exception ex)
            {
                GlobalMessage.Instance.ShowError($"数据加载错误：{ex.Message}");
            }
            finally
            { IsLoading = false; }
        }
        private async Task LoadPPS()
        {
            var resPP = await _service.PPGetAllAsync();
            if (!resPP.Data.IsNullOrEmpty())
            {
                ppsDic = resPP.Data;
            }
            return;
        }
        private async Task LoadFromApi()
        {
            var validationResults = QueryDto.Validate(new ValidationContext(QueryDto)).ToList();
            QueryDto.PageIndex = PageIndex;
            QueryDto.PageSize = PageSize;
            var res = await _service.GetByPage(QueryDto);
            if (res.StatusCode != 200)
            {
                GlobalMessage.Instance.ShowError(JSON.Serialize(res.Errors));
                return;
            }
            PageSize = res.Data.PageSize;
            TotalPages = res.Data.TotalPages;
            TotalCount = res.Data.TotalCount;
            HasNextPages = res.Data.HasNextPages;
            HasPrevPages = res.Data.HasPrevPages;
            PageIndex = res.Data.PageIndex;
            foreach (var item in res.Data.Items)
            {
                if (!_rolesDic.TryGetValue(item.RoleId.Value, out var role))
                    continue;
                item.RoleName = role.Name;
                var pps = ppsDic.FindAll(q => q.PersonID == item.Id);
                if (pps.IsNullOrEmpty())
                    continue;
                item.ProjectName = "";
                foreach (var p in pps)
                {
                    if (_projectNameDic.TryGetValue(p.ProjectID, out var nameP))
                        item.ProjectName += $"{nameP}/";
                }
                item.ProjectName = item.ProjectName.TrimEnd('/');
            }
            Persons = new(res.Data.Items);
        }
    }
}